package com.xmy.cultivate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xmy.cultivate.entity.*;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmy.cultivate.enums.StatusSchedulingEnum;
import com.xmy.cultivate.mapper.LackCourseLogMapper;
import com.xmy.cultivate.mapper.RecordCourseMapper;
import com.xmy.cultivate.respons.LackCourseLogRs;
import com.xmy.cultivate.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmy.cultivate.util.CommonUtil;
import com.xmy.cultivate.util.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 缺课记录 服务实现类
 * </p>
 *
 * @author hpiggy
 * @since 2023-07-28
 */
@Service
public class LackCourseLogServiceImpl extends ServiceImpl<LackCourseLogMapper, LackCourseLog> implements ILackCourseLogService {

    @Autowired
    LackCourseLogMapper lackCourseLogMapper;

    @Autowired
    @Lazy
    IQuarterService iQuarterService;

    @Autowired
    @Lazy
    ICourseSchedulingAlwaysService iCourseSchedulingAlwaysService;

    @Autowired
    @Lazy
    IRecordCourseService iRecordCourseService;

    @Autowired
    @Lazy
    RecordCourseMapper recordCourseMapper;

    @Autowired
    @Lazy
    IGradeService iGradeService;

    @Autowired
    ICourseSchedulingDetailService iCourseSchedulingDetailService;

    @Autowired
    IdWorker idWorker;

    @Autowired
    IStudentGradeService iStudentGradeService;

    @Autowired
    IStudentNewsService iStudentNewsService;


    /**
     * 添加缺课数据
     *
     * @return
     */
    public boolean addLack(Long studentId) {
        LocalDate nowDate = LocalDate.now();
        QueryWrapper<CourseSchedulingAlways> courseSchedulingAlwaysQueryWrapper = new QueryWrapper<>();
        courseSchedulingAlwaysQueryWrapper.le("start_date", nowDate);
        courseSchedulingAlwaysQueryWrapper.le("end_date", nowDate);

        return true;
    }

    @Override
    public IPage<LackCourseLog> getLackCourseLog(Page<LackCourseLog> page, Wrapper wrapper) {
        return lackCourseLogMapper.getLackCourseLog(page, wrapper);
    }

    @Override
    public Boolean updateRemarkBoolean(Integer isRepair, Long repairId, Long id) {
        return lackCourseLogMapper.updateRemarkBoolean(isRepair, repairId, id);
    }


    /**
     * 此接口作废
     *
     * @param yearPart
     * @param quarterNum
     * @param schoolId    校区id
     * @param studentId   学生id
     * @param yearClassId 年级id
     * @param yearClassId
     * @param gradeId
     * @param type        1正常排课，5转课
     * @return
     */
    public boolean addLackCourseLogBatch(Integer yearPart, Integer quarterNum, Long schoolId, Long studentId, Long subjectsId, Integer yearClassId, Long gradeId, Integer type) {

        Grade grade = iGradeService.getById(gradeId);
        Quarter quarter = iQuarterService.getNowQuarter();
        LocalDateTime nowDateTime = LocalDateTime.now().withNano(0);
        LocalDate nowDate = LocalDate.now();
        Integer gradeSectionId = CommonUtil.getGradeSectionId(yearClassId);
        if (gradeSectionId == null) {
            return false;
        }

        //当日的
        QueryWrapper<CourseSchedulingAlways> courseSchedulingAlwaysQueryWrapper = new QueryWrapper<>();
        courseSchedulingAlwaysQueryWrapper.eq("year_part", yearPart);
        courseSchedulingAlwaysQueryWrapper.eq("quarter_num", quarterNum);
        courseSchedulingAlwaysQueryWrapper.eq("grade_section", gradeSectionId);

        courseSchedulingAlwaysQueryWrapper.le("start_date", nowDate);
        courseSchedulingAlwaysQueryWrapper.ge("end_date", nowDate);
        courseSchedulingAlwaysQueryWrapper.last("limit 1");
        CourseSchedulingAlways courseSchedulingAlways = iCourseSchedulingAlwaysService.getOne(courseSchedulingAlwaysQueryWrapper);

        Long useCourseCount = iStudentGradeService.getStudentUseCourseCount(yearPart, quarterNum, subjectsId, schoolId, studentId, grade.getLessonType());

        QueryWrapper<LackCourseLog> lackCourseLogQueryWrapper = new QueryWrapper<>();
        if (courseSchedulingAlways != null) {
            lackCourseLogQueryWrapper.eq("lesson_type", grade.getLessonType());
            lackCourseLogQueryWrapper.eq("student_id", studentId);
            lackCourseLogQueryWrapper.eq("subjects_id", subjectsId);
            lackCourseLogQueryWrapper.eq("year_part", yearPart);
            lackCourseLogQueryWrapper.eq("quarter_num", quarterNum);
            lackCourseLogQueryWrapper.eq("grade_section", gradeSectionId);
            lackCourseLogQueryWrapper.last("limit 1");
            Long lackCourseLogCount = this.count(lackCourseLogQueryWrapper);
            lackCourseLogQueryWrapper.clear();
            if (((useCourseCount / 3) + lackCourseLogCount) < 15) {
                QueryWrapper<CourseSchedulingDetail> courseSchedulingDetailQueryWrapper = new QueryWrapper<>();
                courseSchedulingDetailQueryWrapper.between("school_date", courseSchedulingAlways.getStartDate(), courseSchedulingAlways.getEndDate());
                courseSchedulingDetailQueryWrapper.eq("type", 1);//1正常排课，2调课（改变了上课时间新增的数据）
                courseSchedulingDetailQueryWrapper.le("end_date_time", nowDateTime);
                courseSchedulingDetailQueryWrapper.eq("lesson_type", grade.getLessonType());
                courseSchedulingDetailQueryWrapper.last("limit 1");
                CourseSchedulingDetail courseSchedulingDetail = iCourseSchedulingDetailService.getOne(courseSchedulingDetailQueryWrapper);
                if (courseSchedulingDetail != null) {
                    //记上课中是否已经上过课，没有上过课，表示缺课
                    Integer count = recordCourseMapper.getStudentUpClassCount(schoolId, studentId, subjectsId, yearPart, quarterNum, grade.getLessonType(), courseSchedulingAlways.getStartDate(), courseSchedulingAlways.getEndDate());
                    if (count.equals(0)) {
                        lackCourseLogQueryWrapper.eq("scheduling_always_id", courseSchedulingAlways.getId());
                        lackCourseLogQueryWrapper.eq("student_id", studentId);
                        lackCourseLogQueryWrapper.eq("subjects_id", subjectsId);
                        lackCourseLogQueryWrapper.eq("year_part", yearPart);
                        lackCourseLogQueryWrapper.eq("quarter_num", quarterNum);
                        lackCourseLogQueryWrapper.eq("lesson_type", grade.getLessonType());
                        lackCourseLogQueryWrapper.eq("grade_section", gradeSectionId);
                        lackCourseLogQueryWrapper.last("limit 1");
                        LackCourseLog lackCourseLog = this.getOne(lackCourseLogQueryWrapper);
                        if (lackCourseLog == null) {
                            lackCourseLog = new LackCourseLog();
                            lackCourseLog.setId(idWorker.nextId());
                            lackCourseLog.setSchoolId(schoolId);
                            lackCourseLog.setGradeId(grade.getId());
                            lackCourseLog.setType(type);
                            lackCourseLog.setGradeSection(gradeSectionId);
                            lackCourseLog.setYearPart(yearPart);
                            lackCourseLog.setQuarterNum(quarterNum);
                            lackCourseLog.setStudentId(studentId);
                            lackCourseLog.setYearClassId(grade.getYearClassId().getKey());
                            lackCourseLog.setSubjectsId(subjectsId);
                            lackCourseLog.setLessonType(grade.getLessonType());
                            lackCourseLog.setSchedulingAlwaysId(courseSchedulingAlways.getId());
                            this.save(lackCourseLog);
                        } else {
                            //已添加过缺课记录，但是没有补过课的
                            if (!lackCourseLog.getIsSignIn().equals(1) && !lackCourseLog.getStatus().equals(1)) {
                                lackCourseLog.setGradeId(grade.getId());
                                lackCourseLog.setSchoolId(grade.getSchoolId());
                                lackCourseLog.setType(type);
                                this.updateById(lackCourseLog);
                            }
                        }
                    }
                }
            }
        }

        //当日之前的
        courseSchedulingAlwaysQueryWrapper.clear();
        courseSchedulingAlwaysQueryWrapper.eq("year_part", yearPart);
        courseSchedulingAlwaysQueryWrapper.eq("quarter_num", quarterNum);
        courseSchedulingAlwaysQueryWrapper.eq("grade_section", gradeSectionId);

        courseSchedulingAlwaysQueryWrapper.le("end_date", nowDate);
        courseSchedulingAlwaysQueryWrapper.orderByAsc("num");

        List<CourseSchedulingAlways> courseSchedulingAlwaysList = iCourseSchedulingAlwaysService.list(courseSchedulingAlwaysQueryWrapper);

        lackCourseLogQueryWrapper.clear();

        for (CourseSchedulingAlways courseSchedulingAlwaysItem : courseSchedulingAlwaysList) {
            //记上课中是否已经上过课，没有上过课，表示缺课
            lackCourseLogQueryWrapper.eq("student_id", studentId);
            lackCourseLogQueryWrapper.eq("subjects_id", subjectsId);
            lackCourseLogQueryWrapper.eq("year_part", yearPart);
            lackCourseLogQueryWrapper.eq("quarter_num", quarterNum);
            lackCourseLogQueryWrapper.eq("grade_section", gradeSectionId);
            lackCourseLogQueryWrapper.eq("lesson_type", grade.getLessonType());
            lackCourseLogQueryWrapper.last("limit 1");
            Long lackCourseLogCount = this.count(lackCourseLogQueryWrapper);
            if (((useCourseCount / 3) + lackCourseLogCount) >= 15) {
                continue;
            }

            lackCourseLogQueryWrapper.clear();

            Integer count = recordCourseMapper.getStudentUpClassCount(schoolId, studentId, subjectsId, yearPart, quarterNum, grade.getLessonType(), courseSchedulingAlwaysItem.getStartDate(), courseSchedulingAlwaysItem.getEndDate());
            if (count.equals(0)) {
                lackCourseLogQueryWrapper.eq("scheduling_always_id", courseSchedulingAlwaysItem.getId());
                lackCourseLogQueryWrapper.eq("student_id", studentId);
                lackCourseLogQueryWrapper.eq("subjects_id", subjectsId);
                lackCourseLogQueryWrapper.eq("year_part", yearPart);
                lackCourseLogQueryWrapper.eq("quarter_num", quarterNum);
                lackCourseLogQueryWrapper.eq("grade_section", gradeSectionId);
                lackCourseLogQueryWrapper.eq("lesson_type", grade.getLessonType());
                lackCourseLogQueryWrapper.last("limit 1");
                LackCourseLog lackCourseLog = this.getOne(lackCourseLogQueryWrapper);
                if (lackCourseLog == null) {
                    lackCourseLog = new LackCourseLog();
                    lackCourseLog.setId(idWorker.nextId());
                    lackCourseLog.setSchoolId(schoolId);
                    lackCourseLog.setGradeId(grade.getId());
                    lackCourseLog.setType(type);
                    lackCourseLog.setGradeSection(gradeSectionId);
                    lackCourseLog.setYearPart(yearPart);
                    lackCourseLog.setQuarterNum(quarterNum);
                    lackCourseLog.setStudentId(studentId);
                    lackCourseLog.setYearClassId(grade.getYearClassId().getKey());
                    lackCourseLog.setSubjectsId(subjectsId);
                    lackCourseLog.setLessonType(grade.getLessonType());
                    lackCourseLog.setSchedulingAlwaysId(courseSchedulingAlwaysItem.getId());
                    this.save(lackCourseLog);
                } else {
                    //已添加过缺课记录，但是没有补过课的
                    if (!lackCourseLog.getIsSignIn().equals(1) && !lackCourseLog.getStatus().equals(1)) {
                        lackCourseLog.setGradeId(grade.getId());
                        lackCourseLog.setSchoolId(grade.getSchoolId());
                        lackCourseLog.setType(type);
                        this.updateById(lackCourseLog);
                    }
                }
            }
            lackCourseLogQueryWrapper.clear();
        }
        return true;
    }

    @Override
    public boolean batchAdd(Integer yearPart, Integer quarterNum, Long schoolId, Long studentId, Long subjectsId, Integer yearClassId, Long gradeId, Integer type, Integer lackType) {
        Grade grade = iGradeService.getById(gradeId);
        Integer gradeSectionId = CommonUtil.getGradeSectionId(yearClassId);
        if (gradeSectionId == null) {
            return false;
        }

        QueryWrapper<CourseSchedulingDetail> courseSchedulingDetailQueryWrapper = new QueryWrapper<>();
        courseSchedulingDetailQueryWrapper.eq("grade_id", grade.getId());
        Integer minLessonNum = recordCourseMapper.getMinLessonNum(schoolId, studentId, subjectsId, yearPart, quarterNum, grade.getLessonType());
        if (minLessonNum > 0) {
            courseSchedulingDetailQueryWrapper.lt("lesson_num", minLessonNum);//小于课次
        } else {
            courseSchedulingDetailQueryWrapper.le("school_date", LocalDate.now());//小于等于时间
        }
        courseSchedulingDetailQueryWrapper.orderByAsc("school_date");
        List<CourseSchedulingDetail> courseSchedulingDetailList = iCourseSchedulingDetailService.list(courseSchedulingDetailQueryWrapper);

        QueryWrapper<LackCourseLog> lackCourseLogQueryWrapper = new QueryWrapper<>();
        for (CourseSchedulingDetail courseSchedulingDetail : courseSchedulingDetailList) {
            //如果排课还未记上课，不需要添加到缺少，扣课时时为添加到到课或者请假
            if (courseSchedulingDetail.getSchoolDate().equals(LocalDate.now()) && courseSchedulingDetail.getStatus().equals(StatusSchedulingEnum.NO)) {
                continue;
            }
            if (courseSchedulingDetail.getLessonNum() == null || courseSchedulingDetail.getLessonNum() > 15) {
                continue;
            }

            // 判断是否在新生表
            QueryWrapper<StudentNews> studentNewsQueryWrapper = new QueryWrapper<>();
            studentNewsQueryWrapper.eq("student_id", studentId);
            studentNewsQueryWrapper.eq("year_part", grade.getYearPart());
            studentNewsQueryWrapper.eq("quarter_num", grade.getQuarterNum());
            studentNewsQueryWrapper.eq("subjects_id", grade.getSubjectsId());
            studentNewsQueryWrapper.last("limit 1");
            StudentNews studentNews = iStudentNewsService.getOne(studentNewsQueryWrapper);
            if (studentNews == null) {
                Integer count = recordCourseMapper.getStudentUpClassCountForLessonNum(schoolId, studentId, subjectsId, yearPart, quarterNum, grade.getLessonType(), courseSchedulingDetail.getLessonNum());
                if (count.equals(0)) {
                    lackCourseLogQueryWrapper.eq("student_id", studentId);
                    lackCourseLogQueryWrapper.eq("subjects_id", subjectsId);
                    lackCourseLogQueryWrapper.eq("year_part", yearPart);
                    lackCourseLogQueryWrapper.eq("quarter_num", quarterNum);
                    lackCourseLogQueryWrapper.eq("lesson_type", grade.getLessonType());
                    lackCourseLogQueryWrapper.eq("lesson_num", courseSchedulingDetail.getLessonNum());
                    lackCourseLogQueryWrapper.last("limit 1");
                    LackCourseLog lackCourseLog = this.getOne(lackCourseLogQueryWrapper);
                    if (lackCourseLog == null) {
                        lackCourseLog = new LackCourseLog();
                        lackCourseLog.setId(idWorker.nextId());
                        lackCourseLog.setSchoolId(schoolId);
                        lackCourseLog.setGradeId(grade.getId());
                        lackCourseLog.setType(type);
                        lackCourseLog.setGradeSection(gradeSectionId);
                        lackCourseLog.setYearPart(yearPart);
                        lackCourseLog.setQuarterNum(quarterNum);
                        lackCourseLog.setStudentId(studentId);
                        lackCourseLog.setYearClassId(grade.getYearClassId().getKey());
                        lackCourseLog.setSubjectsId(subjectsId);
                        lackCourseLog.setLessonType(grade.getLessonType());
                        lackCourseLog.setLessonNum(courseSchedulingDetail.getLessonNum());
                        lackCourseLog.setSchedulingAlwaysId(courseSchedulingDetail.getId());
                        lackCourseLog.setLackType(lackType);
                        this.save(lackCourseLog);
                    }
                }
            } else {
                Quarter quarter = iQuarterService.getQuarterForYearAndNum(yearPart, quarterNum);
                if (quarter.getType() == 1) {
                    // 学期班
//                    if (studentNews.getIsAddLack() == 1) {
                    // 添加所有的缺课
                    iCourseSchedulingDetailService.resumeClassesLackCourse(grade.getId(), studentId, type, null, lackType);
//                    } else {
//                        // 添加created_at时间之后的排课缺课
//                        LocalDateTime createdAt = studentNews.getCreatedAt();
//                        iCourseSchedulingDetailService.resumeClassesLackCourse(grade.getId(), studentId, type, String.valueOf(createdAt));
//                    }
                } else {
                    // 假期班，添加所有的缺课
                    iCourseSchedulingDetailService.resumeClassesLackCourse(grade.getId(), studentId, type, null, lackType);
                }
            }
            lackCourseLogQueryWrapper.clear();
        }
        lackCourseLogQueryWrapper.clear();
        lackCourseLogQueryWrapper.eq("student_id", studentId);
        lackCourseLogQueryWrapper.eq("subjects_id", subjectsId);
        lackCourseLogQueryWrapper.eq("year_part", yearPart);
        lackCourseLogQueryWrapper.eq("quarter_num", quarterNum);
        lackCourseLogQueryWrapper.eq("grade_section", gradeSectionId);
        lackCourseLogQueryWrapper.eq("lesson_type", grade.getLessonType());
        List<LackCourseLog> lackCourseLogList = this.list(lackCourseLogQueryWrapper);

        for (LackCourseLog lackCourseLog : lackCourseLogList) {
            //已添加过缺课记录，但是没有补过课的
            if (!lackCourseLog.getIsSignIn().equals(1) && !lackCourseLog.getStatus().equals(1)) {
                lackCourseLog.setGradeId(grade.getId());
                lackCourseLog.setSchoolId(grade.getSchoolId());
                lackCourseLog.setType(type);
                this.updateById(lackCourseLog);
            }
        }
        return true;
    }


    public LackCourseLog getLackCoruseLogForStudent(Integer yearPart, Integer quarterNum, Long studentId, Long subjectsId, Integer lessonNum) {
        return lackCourseLogMapper.getLackCoruseLogForStudent(yearPart, quarterNum, studentId, subjectsId, lessonNum);
    }

    @Override
    public Integer getLackCourseForNum(Integer yearPart, Integer quarterNum, Long studentId, Long subjectsId, Integer lessonNum, Integer lessonType) {
        return lackCourseLogMapper.getLackCourseForNum(yearPart, quarterNum, studentId, subjectsId, lessonNum, lessonType);
    }

    @Override
    public IPage<LackCourseLogRs> lackStudentList(IPage<?> page, Integer yearPart, Integer quarterNum, String schoolId, String yearClassId, String gradeId, String subjectsId, String teacherId, String classTypeId, String lackType, String studentName, String idStr) {
        return lackCourseLogMapper.lackStudentList(page, yearPart, quarterNum, schoolId, yearClassId, gradeId, subjectsId, teacherId, classTypeId, lackType, studentName, idStr);
    }

    @Override
    public Boolean updateLackTypeBoolean(Integer lackType, Long gradeId, Long studentId, Integer yearPart, Integer quarterNum) {
        return lackCourseLogMapper.updateLackTypeBoolean(lackType, gradeId, studentId, yearPart, quarterNum);
    }

    @Override
    public Boolean cancelLackBoolean(Long gradeId, Long studentId, Integer yearPart, Integer quarterNum) {
        return lackCourseLogMapper.cancelLackBoolean(gradeId, studentId, yearPart, quarterNum);
    }

    @Override
    public Boolean cancelRepairCourseBoolean(Long gradeId, Long studentId, Integer yearPart, Integer quarterNum) {
        return lackCourseLogMapper.cancelRepairCourseBoolean(gradeId, studentId, yearPart, quarterNum);
    }

}
